home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 November / november_2001.iso / Browsers / Netscape 6.1 / browser.xpi / bin / chrome / comm.jar / content / editor / ComposerCommands.js next >
Encoding:
JavaScript  |  2001-07-09  |  45.3 KB  |  1,554 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  *
  13.  * The Original Code is mozilla.org code.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  *
  20.  * Contributor(s): 
  21.  *    Simon Fraser (sfraser@netscape.com)
  22.  *    Ryan Cassin (rcassin@supernova.org)
  23.  */
  24.  
  25. /* Implementations of nsIControllerCommand for composer commands */
  26.  
  27.  
  28. //-----------------------------------------------------------------------------------
  29. function SetupHTMLEditorCommands()
  30. {
  31.   var controller = GetEditorController();
  32.   if (!controller)
  33.     return;
  34.   
  35.  
  36.   // Include everthing a text editor does
  37.   SetupTextEditorCommands();
  38.  
  39.   //dump("Registering HTML editor commands\n");
  40.  
  41.   controller.registerCommand("cmd_renderedHTMLEnabler",           nsDummyHTMLCommand);
  42.  
  43.   controller.registerCommand("cmd_listProperties",  nsListPropertiesCommand);
  44.   controller.registerCommand("cmd_pageProperties",  nsPagePropertiesCommand);
  45.   controller.registerCommand("cmd_colorProperties", nsColorPropertiesCommand);
  46.   controller.registerCommand("cmd_advancedProperties", nsAdvancedPropertiesCommand);
  47.   controller.registerCommand("cmd_objectProperties",   nsObjectPropertiesCommand);
  48.   controller.registerCommand("cmd_removeLinks",        nsRemoveLinksCommand);
  49.   
  50.   controller.registerCommand("cmd_image",         nsImageCommand);
  51.   controller.registerCommand("cmd_hline",         nsHLineCommand);
  52.   controller.registerCommand("cmd_link",          nsLinkCommand);
  53.   controller.registerCommand("cmd_anchor",        nsAnchorCommand);
  54.   controller.registerCommand("cmd_insertHTML",    nsInsertHTMLCommand);
  55.   controller.registerCommand("cmd_insertBreak",   nsInsertBreakCommand);
  56.   controller.registerCommand("cmd_insertBreakAll",nsInsertBreakAllCommand);
  57.  
  58.   controller.registerCommand("cmd_table",              nsInsertOrEditTableCommand);
  59.   controller.registerCommand("cmd_editTable",          nsEditTableCommand);
  60.   controller.registerCommand("cmd_SelectTable",        nsSelectTableCommand);
  61.   controller.registerCommand("cmd_SelectRow",          nsSelectTableRowCommand);
  62.   controller.registerCommand("cmd_SelectColumn",       nsSelectTableColumnCommand);
  63.   controller.registerCommand("cmd_SelectCell",         nsSelectTableCellCommand);
  64.   controller.registerCommand("cmd_SelectAllCells",     nsSelectAllTableCellsCommand);
  65.   controller.registerCommand("cmd_InsertTable",        nsInsertTableCommand);
  66.   controller.registerCommand("cmd_InsertRowAbove",     nsInsertTableRowAboveCommand);
  67.   controller.registerCommand("cmd_InsertRowBelow",     nsInsertTableRowBelowCommand);
  68.   controller.registerCommand("cmd_InsertColumnBefore", nsInsertTableColumnBeforeCommand);
  69.   controller.registerCommand("cmd_InsertColumnAfter",  nsInsertTableColumnAfterCommand);
  70.   controller.registerCommand("cmd_InsertCellBefore",   nsInsertTableCellBeforeCommand);
  71.   controller.registerCommand("cmd_InsertCellAfter",    nsInsertTableCellAfterCommand);
  72.   controller.registerCommand("cmd_DeleteTable",        nsDeleteTableCommand);
  73.   controller.registerCommand("cmd_DeleteRow",          nsDeleteTableRowCommand);
  74.   controller.registerCommand("cmd_DeleteColumn",       nsDeleteTableColumnCommand);
  75.   controller.registerCommand("cmd_DeleteCell",         nsDeleteTableCellCommand);
  76.   controller.registerCommand("cmd_DeleteCellContents", nsDeleteTableCellContentsCommand);
  77.   controller.registerCommand("cmd_JoinTableCells",     nsJoinTableCellsCommand);
  78.   controller.registerCommand("cmd_SplitTableCell",     nsSplitTableCellCommand);
  79.   controller.registerCommand("cmd_TableOrCellColor",   nsTableOrCellColorCommand);
  80.   controller.registerCommand("cmd_NormalizeTable",     nsNormalizeTableCommand);
  81.   controller.registerCommand("cmd_FinishHTMLSource",   nsFinishHTMLSource);
  82.   controller.registerCommand("cmd_CancelHTMLSource",   nsCancelHTMLSource);
  83.   controller.registerCommand("cmd_smiley",             nsSetSmiley);
  84.   controller.registerCommand("cmd_buildRecentPagesMenu", nsBuildRecentPagesMenu);
  85.   controller.registerCommand("cmd_ConvertToTable",     nsConvertToTable);
  86. }
  87.  
  88. function SetupTextEditorCommands()
  89. {
  90.   var controller = GetEditorController();
  91.   if (!controller)
  92.     return;
  93.   
  94.   //dump("Registering plain text editor commands\n");
  95.   
  96.   controller.registerCommand("cmd_find",       nsFindCommand);
  97.   controller.registerCommand("cmd_findNext",   nsFindNextCommand);
  98.   controller.registerCommand("cmd_spelling",   nsSpellingCommand);
  99.   controller.registerCommand("cmd_insertChars", nsInsertCharsCommand);
  100. }
  101.  
  102. function SetupComposerWindowCommands()
  103. {
  104.   // Create a command controller and register commands
  105.   //   specific to Web Composer window (file-related commands, HTML Source...)
  106.   // IMPORTANT: For each of these commands, the doCommand method 
  107.   //            must first call FinishHTMLSource() 
  108.   //            to go from HTML Source mode to any other edit mode
  109.  
  110.   var windowCommandManager = window.controllers;
  111.  
  112.   if (!windowCommandManager) return;
  113.  
  114.   var composerController = Components.classes["@mozilla.org/editor/composercontroller;1"].createInstance();
  115.   if (!composerController)
  116.   {
  117.     dump("Failed to create composerController\n");
  118.     return;
  119.   }
  120.  
  121.   var editorController = composerController.QueryInterface(Components.interfaces.nsIEditorController);
  122.   if (!editorController)
  123.   {
  124.     dump("Failed to get interface for nsIEditorController\n");
  125.     return;
  126.   }
  127.  
  128.   // Note: We init with the editorShell for the main composer window, not the HTML Source textfield?
  129.   editorController.Init(window.editorShell);
  130.  
  131.   var interfaceRequestor = composerController.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  132.   if (!interfaceRequestor)
  133.   {
  134.     dump("Failed to get iterfaceRequestor for composerController\n");
  135.     return;
  136.   }
  137.     
  138.  
  139.   // Get the nsIControllerCommandManager interface we need to register more commands
  140.   var commandManager = interfaceRequestor.getInterface(Components.interfaces.nsIControllerCommandManager);
  141.   if (!commandManager)
  142.   {
  143.     dump("Failed to get interface for nsIControllerCommandManager\n");
  144.     return;
  145.   }
  146.  
  147.   // File-related commands
  148.   commandManager.registerCommand("cmd_newEditor",      nsNewEditorCommand);
  149.   commandManager.registerCommand("cmd_open",           nsOpenCommand);
  150.   commandManager.registerCommand("cmd_save",           nsSaveCommand);
  151.   commandManager.registerCommand("cmd_saveAs",         nsSaveAsCommand);
  152.   commandManager.registerCommand("cmd_exportToText",   nsExportToTextCommand);
  153.   commandManager.registerCommand("cmd_saveAsCharset",  nsSaveAsCharsetCommand);
  154.   commandManager.registerCommand("cmd_revert",         nsRevertCommand);
  155.   commandManager.registerCommand("cmd_openRemote",     nsOpenRemoteCommand);
  156.   commandManager.registerCommand("cmd_preview",        nsPreviewCommand);
  157.   commandManager.registerCommand("cmd_editSendPage",   nsSendPageCommand);
  158.   commandManager.registerCommand("cmd_quit",           nsQuitCommand);
  159.   commandManager.registerCommand("cmd_close",          nsCloseCommand);
  160.   commandManager.registerCommand("cmd_preferences",    nsPreferencesCommand);
  161.  
  162.   // Edit Mode commands
  163.   if (window.editorShell.editorType == "html")
  164.   {
  165.     commandManager.registerCommand("cmd_NormalMode",         nsNormalModeCommand);
  166.     commandManager.registerCommand("cmd_AllTagsMode",        nsAllTagsModeCommand);
  167.     commandManager.registerCommand("cmd_HTMLSourceMode",     nsHTMLSourceModeCommand);
  168.     commandManager.registerCommand("cmd_PreviewMode",        nsPreviewModeCommand);
  169.     commandManager.registerCommand("cmd_FinishHTMLSource",   nsFinishHTMLSource);
  170.     commandManager.registerCommand("cmd_CancelHTMLSource",   nsCancelHTMLSource);
  171.   }
  172.  
  173.   windowCommandManager.insertControllerAt(0, editorController);
  174. }
  175.  
  176. //-----------------------------------------------------------------------------------
  177. function GetEditorController()
  178. {
  179.   var numControllers = window._content.controllers.getControllerCount();
  180.     
  181.   // count down to find a controller that supplies a nsIControllerCommandManager interface
  182.   for (var i = numControllers; i >= 0 ; i --)
  183.   {
  184.     var commandManager = null;
  185.     
  186.     try { 
  187.       var controller = window._content.controllers.getControllerAt(i);
  188.       
  189.       var interfaceRequestor = controller.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  190.       if (!interfaceRequestor) continue;
  191.     
  192.       commandManager = interfaceRequestor.getInterface(Components.interfaces.nsIControllerCommandManager);
  193.     }
  194.     catch(ex)
  195.     {
  196.         //dump(ex + "\n");
  197.     }
  198.  
  199.     if (commandManager)
  200.       return commandManager;
  201.   }
  202.  
  203.   dump("Failed to find a controller to register commands with\n");
  204.   return null;
  205. }
  206.  
  207. //-----------------------------------------------------------------------------------
  208. function goUpdateComposerMenuItems(commandset)
  209. {
  210.   // dump("Updating commands for " + commandset.id + "\n");
  211.   
  212.   for (var i = 0; i < commandset.childNodes.length; i++)
  213.   {
  214.     var commandID = commandset.childNodes[i].getAttribute("id");
  215.     if (commandID)
  216.     {
  217.       goUpdateCommand(commandID);
  218.     }
  219.   }
  220. }
  221.  
  222. //-----------------------------------------------------------------------------------
  223. function PrintObject(obj)
  224. {
  225.   dump("-----" + obj + "------\n");
  226.   var names = "";
  227.   for (var i in obj)
  228.   {
  229.     if (i == "value")
  230.       names += i + ": " + obj.value + "\n";
  231.     else if (i == "id")
  232.       names += i + ": " + obj.id + "\n";
  233.     else
  234.       names += i + "\n";
  235.   }
  236.   
  237.   dump(names + "-----------\n");
  238. }
  239.  
  240. //-----------------------------------------------------------------------------------
  241. function PrintNodeID(id)
  242. {
  243.   PrintObject(document.getElementById(id));
  244. }
  245.  
  246. //-----------------------------------------------------------------------------------
  247. var nsDummyHTMLCommand =
  248. {
  249.   isCommandEnabled: function(aCommand, dummy)
  250.   {
  251.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  252.   },
  253.  
  254.   doCommand: function(aCommand)
  255.   {
  256.     // do nothing
  257.     dump("Hey, who's calling the dummy command?\n");
  258.   }
  259.  
  260. };
  261.  
  262. //-----------------------------------------------------------------------------------
  263. var nsOpenCommand =
  264. {
  265.   isCommandEnabled: function(aCommand, dummy)
  266.   {
  267.     return true;    // we can always do this
  268.   },
  269.  
  270.   doCommand: function(aCommand)
  271.   {
  272.     var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  273.     fp.init(window, window.editorShell.GetString("OpenHTMLFile"), nsIFilePicker.modeOpen);
  274.   
  275.     // When loading into Composer, direct user to prefer HTML files and text files,
  276.     //   so we call separately to control the order of the filter list
  277.     fp.appendFilters(nsIFilePicker.filterHTML);
  278.     fp.appendFilters(nsIFilePicker.filterText);
  279.     fp.appendFilters(nsIFilePicker.filterAll);
  280.  
  281.     /* doesn't handle *.shtml files */
  282.     try {
  283.       fp.show();
  284.       /* need to handle cancel (uncaught exception at present) */
  285.     }
  286.     catch (ex) {
  287.       dump("filePicker.chooseInputFile threw an exception\n");
  288.     }
  289.   
  290.     /* This checks for already open window and activates it... 
  291.      * note that we have to test the native path length
  292.      *  since fileURL.spec will be "file:///" if no filename picked (Cancel button used)
  293.      */
  294.     if (fp.file && fp.file.path.length > 0) {
  295.       EditorOpenUrl(fp.fileURL.spec);
  296.     }
  297.   }
  298. };
  299.  
  300. //-----------------------------------------------------------------------------------
  301. var nsSaveCommand =
  302. {
  303.   isCommandEnabled: function(aCommand, dummy)
  304.   {
  305.     return window.editorShell && 
  306.       (window.editorShell.documentModified || 
  307.        window.editorShell.editorDocument.location == "about:blank" ||
  308.        window.gHTMLSourceChanged);
  309.   },
  310.   
  311.   doCommand: function(aCommand)
  312.   {
  313.     if (window.editorShell)
  314.     {
  315.       FinishHTMLSource(); // In editor.js
  316.       var doSaveAs = window.editorShell.editorDocument.location == "about:blank";
  317.       var result = window.editorShell.saveDocument(doSaveAs, false, editorShell.contentsMIMEType);
  318.       window._content.focus();
  319.       return result;
  320.     }
  321.     return false;
  322.   }
  323. }
  324.  
  325. var nsSaveAsCommand =
  326. {
  327.   isCommandEnabled: function(aCommand, dummy)
  328.   {
  329.     return (window.editorShell && window.editorShell.documentEditable);
  330.   },
  331.  
  332.   doCommand: function(aCommand)
  333.   {
  334.     if (window.editorShell)
  335.     {
  336.       FinishHTMLSource();
  337.       var result = window.editorShell.saveDocument(true, false, editorShell.contentsMIMEType);
  338.       window._content.focus();
  339.       return result;
  340.     }
  341.     return false;
  342.   }
  343. }
  344.  
  345. var nsExportToTextCommand =
  346. {
  347.   isCommandEnabled: function(aCommand, dummy)
  348.   {
  349.     return (window.editorShell && window.editorShell.documentEditable);
  350.   },
  351.  
  352.   doCommand: function(aCommand)
  353.   {
  354.     if (window.editorShell)
  355.     {
  356.       FinishHTMLSource();
  357.       var result = window.editorShell.saveDocument(true, true, "text/plain");
  358.       window._content.focus();
  359.       return result;
  360.     }
  361.     return false;
  362.   }
  363. }
  364.  
  365. var nsSaveAsCharsetCommand =
  366. {
  367.   isCommandEnabled: function(aCommand, dummy)
  368.   {
  369.     return (window.editorShell && window.editorShell.documentEditable);
  370.   },
  371.   doCommand: function(aCommand)
  372.   {    
  373.     FinishHTMLSource();
  374.     window.ok = false;
  375.     window.exportToText = false;
  376.     window.openDialog("chrome://editor/content/EditorSaveAsCharset.xul","_blank", "chrome,close,titlebar,modal,resizable=yes");
  377.  
  378.     if (window.newTitle != null) {
  379.       try {
  380.         editorShell.SetDocumentTitle(window.newTitle);
  381.       } 
  382.       catch (ex) {}
  383.     }    
  384.  
  385.     if (window.ok)
  386.     {
  387.       if (window.exportToText)
  388.       {
  389.         window.ok = window.editorShell.saveDocument(true, true, "text/plain");
  390.       }
  391.       else
  392.       {
  393.         window.ok = window.editorShell.saveDocument(true, false, editorShell.contentsMIMEType);
  394.       }
  395.     }
  396.  
  397.     window._content.focus();
  398.     return window.ok;
  399.   }
  400. };
  401.  
  402. //-----------------------------------------------------------------------------------
  403. var nsRevertCommand =
  404. {
  405.   isCommandEnabled: function(aCommand, dummy)
  406.   {
  407.     return (window.editorShell && 
  408.             window.editorShell.documentModified &&
  409.             window.editorShell.editorDocument.location != "about:blank");
  410.   },
  411.  
  412.   doCommand: function(aCommand)
  413.   {
  414.     // Confirm with the user to abandon current changes
  415.     var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
  416.     promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
  417.  
  418.     if (promptService)
  419.     {
  420.       var result = {value:0};
  421.  
  422.       // Put the page title in the message string
  423.       var title = window.editorShell.editorDocument.title;
  424.       if (!title || title.length == 0)
  425.         title = window.editorShell.GetTitle("untitled");
  426.  
  427.       var msg = window.editorShell.GetString("AbandonChanges").replace(/%title%/,title);
  428.  
  429.       promptService.confirmEx(window, window.editorShell.GetString("RevertCaption"), msg,
  430.                                 (promptService.BUTTON_TITLE_REVERT * promptService.BUTTON_POS_0) +
  431.                                 (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
  432.                                 null, null, null, null, {value:0}, result);
  433.  
  434.       // Reload page if first button (Revert) was pressed
  435.       if(result.value == 0)
  436.       {
  437.         FinishHTMLSource();
  438.         window.editorShell.LoadUrl(editorShell.editorDocument.location);
  439.       }
  440.     }
  441.   }
  442. };
  443.  
  444. //-----------------------------------------------------------------------------------
  445. var nsCloseCommand =
  446. {
  447.   isCommandEnabled: function(aCommand, dummy)
  448.   {
  449.     return window.editorShell;
  450.   },
  451.   
  452.   doCommand: function(aCommand)
  453.   {
  454.     CloseWindow();
  455.   }
  456. };
  457.  
  458. function CloseWindow()
  459. {
  460.   // Check to make sure document is saved. "true" means allow "Don't Save" button,
  461.   //   so user can choose to close without saving
  462.   if (CheckAndSaveDocument(window.editorShell.GetString("BeforeClosing"), true)) 
  463.   {
  464.     if (window.InsertCharWindow)
  465.       SwitchInsertCharToAnotherEditorOrClose();
  466.  
  467.     window.editorShell.CloseWindowWithoutSaving();
  468.   }
  469. }
  470.  
  471. //-----------------------------------------------------------------------------------
  472. var nsNewEditorCommand =
  473. {
  474.   isCommandEnabled: function(aCommand, dummy)
  475.   {
  476.     return true;    // we can always do this
  477.   },
  478.  
  479.   doCommand: function(aCommand)
  480.   {
  481.     NewEditorWindow();
  482.   }
  483. };
  484.  
  485. //-----------------------------------------------------------------------------------
  486. var nsOpenRemoteCommand =
  487. {
  488.   isCommandEnabled: function(aCommand, dummy)
  489.   {
  490.     return true;    // we can always do this
  491.   },
  492.  
  493.   doCommand: function(aCommand)
  494.   {
  495.       /* The last parameter is the current browser window.
  496.          Use 0 and the default checkbox will be to load into an editor
  497.          and loading into existing browser option is removed
  498.        */
  499.       window.openDialog( "chrome://communicator/content/openLocation.xul", "_blank", "chrome,modal,titlebar", 0);
  500.     window._content.focus();
  501.   }
  502. };
  503.  
  504. //-----------------------------------------------------------------------------------
  505. var nsPreviewCommand =
  506. {
  507.   isCommandEnabled: function(aCommand, dummy)
  508.   {
  509.     return (window.editorShell && IsEditorContentHTML() && (DocumentHasBeenSaved() || window.editorShell.documentModified));
  510.   },
  511.  
  512.   doCommand: function(aCommand)
  513.   {
  514.       // Don't continue if user canceled during prompt for saving
  515.     // DocumentHasBeenSaved will test if we have a URL and suppress "Don't Save" button if not
  516.     if (!CheckAndSaveDocument(window.editorShell.GetString("BeforePreview"), DocumentHasBeenSaved()))
  517.         return;
  518.  
  519.     // Check if we saved again just in case?
  520.       if (DocumentHasBeenSaved())
  521.         window.openDialog(getBrowserURL(), "EditorPreview", "chrome,all,dialog=no", window._content.location);
  522.   }
  523. };
  524.  
  525. //-----------------------------------------------------------------------------------
  526. var nsSendPageCommand =
  527. {
  528.   isCommandEnabled: function(aCommand, dummy)
  529.   {
  530.     return (window.editorShell != null && (DocumentHasBeenSaved() || window.editorShell.documentModified));
  531.   },
  532.  
  533.   doCommand: function(aCommand)
  534.   {
  535.       // Don't continue if user canceled during prompt for saving
  536.     // DocumentHasBeenSaved will test if we have a URL and suppress "Don't Save" button if not
  537.     if (!CheckAndSaveDocument(window.editorShell.GetString("SendPageReason"), DocumentHasBeenSaved()))
  538.         return;
  539.  
  540.     // Check if we saved again just in case?
  541.       if (DocumentHasBeenSaved())
  542.     {
  543.       // Launch Messenger Composer window with current page as contents
  544.       var pageTitle = window.editorShell.editorDocument.title;
  545.       var pageUrl = window.editorShell.editorDocument.location.href;
  546.       window.openDialog( "chrome://messenger/content/messengercompose/messengercompose.xul", "_blank", 
  547.                          "chrome,all,dialog=no", 
  548.                          "attachment='" + pageUrl.replace(/\,/g, "%2C") + "',body='" + pageUrl +
  549.                          "',subject='" + pageTitle + "',bodyislink=true");
  550.     }
  551.   }
  552. };
  553.  
  554. //-----------------------------------------------------------------------------------
  555. var nsQuitCommand =
  556. {
  557.   isCommandEnabled: function(aCommand, dummy)
  558.   {
  559.     return true;    // we can always do this
  560.   },
  561.  
  562.   doCommand: function(aCommand)
  563.   {
  564.     // In editor.js
  565.     FinishHTMLSource();
  566.     goQuitApplication();
  567.   }
  568. };
  569.  
  570. //-----------------------------------------------------------------------------------
  571. var nsFindCommand =
  572. {
  573.   isCommandEnabled: function(aCommand, dummy)
  574.   {
  575.     return (window.editorShell && !IsInHTMLSourceMode());
  576.   },
  577.  
  578.   doCommand: function(aCommand)
  579.   {
  580.     window.editorShell.Replace();
  581.   }
  582. };
  583.  
  584. //-----------------------------------------------------------------------------------
  585. var nsFindNextCommand =
  586. {
  587.   isCommandEnabled: function(aCommand, dummy)
  588.   {
  589.     // we can only do this if the search pattern is non-empty. Not sure how
  590.     // to get that from here
  591.     return (window.editorShell && !IsInHTMLSourceMode());
  592.   },
  593.  
  594.   doCommand: function(aCommand)
  595.   {
  596.     window.editorShell.FindNext();
  597.   }
  598. };
  599.  
  600. //-----------------------------------------------------------------------------------
  601. var nsSpellingCommand =
  602. {
  603.   isCommandEnabled: function(aCommand, dummy)
  604.   {
  605.     return (window.editorShell != null) && !IsInHTMLSourceMode() && IsSpellCheckerInstalled();
  606.   },
  607.  
  608.   doCommand: function(aCommand)
  609.   {
  610.     try {
  611.       window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
  612.               "chrome,close,titlebar,modal", "");
  613.     }
  614.     catch(ex) {
  615.       dump("*** Exception error: SpellChecker Dialog Closing\n");
  616.     }
  617.     window._content.focus();
  618.   }
  619. };
  620.  
  621. //-----------------------------------------------------------------------------------
  622. var nsImageCommand =
  623. {
  624.   isCommandEnabled: function(aCommand, dummy)
  625.   {
  626.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  627.   },
  628.   doCommand: function(aCommand)
  629.   {
  630.     window.openDialog("chrome://editor/content/EdImageProps.xul","_blank", "chrome,close,titlebar,modal");
  631.     window._content.focus();
  632.   }
  633. };
  634.  
  635. //-----------------------------------------------------------------------------------
  636. var nsHLineCommand =
  637. {
  638.   isCommandEnabled: function(aCommand, dummy)
  639.   {
  640.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  641.   },
  642.   doCommand: function(aCommand)
  643.   {
  644.     // Inserting an HLine is different in that we don't use properties dialog
  645.     //  unless we are editing an existing line's attributes
  646.     //  We get the last-used attributes from the prefs and insert immediately
  647.  
  648.     var tagName = "hr";
  649.     var hLine = window.editorShell.GetSelectedElement(tagName);
  650.  
  651.     if (hLine) {
  652.       // We only open the dialog for an existing HRule
  653.       window.openDialog("chrome://editor/content/EdHLineProps.xul", "_blank", "chrome,close,titlebar,modal");
  654.       window._content.focus();
  655.     } else {
  656.       hLine = window.editorShell.CreateElementWithDefaults(tagName);
  657.  
  658.       if (hLine) {
  659.         // We change the default attributes to those saved in the user prefs
  660.  
  661.         if (gPrefs) {
  662.           try {
  663.             var align = gPrefs.GetIntPref("editor.hrule.align");
  664.             if (align == 0 ) {
  665.               hLine.setAttribute("align", "left");
  666.             } else if (align == 2) {
  667.               hLine.setAttribute("align", "right");
  668.             }
  669.  
  670.             //Note: Default is center (don't write attribute)
  671.         
  672.             var width = gPrefs.GetIntPref("editor.hrule.width");
  673.             var percent = gPrefs.GetBoolPref("editor.hrule.width_percent");
  674.             if (percent)
  675.               width = width +"%";
  676.  
  677.             hLine.setAttribute("width", width);
  678.  
  679.             var height = gPrefs.GetIntPref("editor.hrule.height");
  680.             hLine.setAttribute("size", String(height));
  681.  
  682.             var shading = gPrefs.GetBoolPref("editor.hrule.shading");
  683.             if (shading) {
  684.               hLine.removeAttribute("noshade");
  685.             } else {
  686.               hLine.setAttribute("noshade", "");
  687.             }
  688.           }
  689.           catch (ex) {
  690.             dump("failed to get HLine prefs\n");
  691.           }
  692.         }
  693.         try {
  694.           window.editorShell.InsertElementAtSelection(hLine, true);
  695.         } catch (e) {
  696.           dump("Exception occured in InsertElementAtSelection\n");
  697.         }
  698.       }
  699.     }
  700.   }
  701. };
  702.  
  703. //-----------------------------------------------------------------------------------
  704. var nsLinkCommand =
  705. {
  706.   isCommandEnabled: function(aCommand, dummy)
  707.   {
  708.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  709.   },
  710.   doCommand: function(aCommand)
  711.   {
  712.     window.openDialog("chrome://editor/content/EdLinkProps.xul","_blank", "chrome,close,titlebar,modal");
  713.     window._content.focus();
  714.   }
  715. };
  716.  
  717. //-----------------------------------------------------------------------------------
  718. var nsAnchorCommand =
  719. {
  720.   isCommandEnabled: function(aCommand, dummy)
  721.   {
  722.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  723.   },
  724.   doCommand: function(aCommand)
  725.   {
  726.     window.openDialog("chrome://editor/content/EdNamedAnchorProps.xul", "_blank", "chrome,close,titlebar,modal", "");
  727.     window._content.focus();
  728.   }
  729. };
  730.  
  731. //-----------------------------------------------------------------------------------
  732. var nsInsertHTMLCommand =
  733. {
  734.   isCommandEnabled: function(aCommand, dummy)
  735.   {
  736.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  737.   },
  738.   doCommand: function(aCommand)
  739.   {
  740.     window.openDialog("chrome://editor/content/EdInsSrc.xul","_blank", "chrome,close,titlebar,modal,resizable", "");
  741.     window._content.focus();
  742.   }
  743. };
  744.  
  745. //-----------------------------------------------------------------------------------
  746. var nsInsertCharsCommand =
  747. {
  748.   isCommandEnabled: function(aCommand, dummy)
  749.   {
  750.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  751.   },
  752.   doCommand: function(aCommand)
  753.   {
  754.     EditorFindOrCreateInsertCharWindow();
  755.   }
  756. };
  757.  
  758. //-----------------------------------------------------------------------------------
  759. var nsInsertBreakCommand =
  760. {
  761.   isCommandEnabled: function(aCommand, dummy)
  762.   {
  763.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  764.   },
  765.   doCommand: function(aCommand)
  766.   {
  767.     window.editorShell.InsertSource("<br>");
  768.   }
  769. };
  770.  
  771. //-----------------------------------------------------------------------------------
  772. var nsInsertBreakAllCommand =
  773. {
  774.   isCommandEnabled: function(aCommand, dummy)
  775.   {
  776.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  777.   },
  778.   doCommand: function(aCommand)
  779.   {
  780.     window.editorShell.InsertSource("<br clear='all'>");
  781.   }
  782. };
  783.  
  784. //-----------------------------------------------------------------------------------
  785. var nsListPropertiesCommand =
  786. {
  787.   isCommandEnabled: function(aCommand, dummy)
  788.   {
  789.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  790.   },
  791.   doCommand: function(aCommand)
  792.   {
  793.     window.openDialog("chrome://editor/content/EdListProps.xul","_blank", "chrome,close,titlebar,modal");
  794.     window._content.focus();
  795.   }
  796. };
  797.  
  798.  
  799. //-----------------------------------------------------------------------------------
  800. var nsPagePropertiesCommand =
  801. {
  802.   isCommandEnabled: function(aCommand, dummy)
  803.   {
  804.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  805.   },
  806.   doCommand: function(aCommand)
  807.   {
  808.     window.openDialog("chrome://editor/content/EdPageProps.xul","_blank", "chrome,close,titlebar,modal", "");
  809.     window._content.focus();
  810.   }
  811. };
  812.  
  813. //-----------------------------------------------------------------------------------
  814. var nsObjectPropertiesCommand =
  815. {
  816.   isCommandEnabled: function(aCommand, dummy)
  817.   {
  818.     var isEnabled = false;
  819.     if (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML())
  820.     {
  821.       isEnabled = (GetObjectForProperties() != null ||
  822.                    window.editorShell.GetSelectedElement("href") != null);
  823.     }
  824.     return isEnabled;
  825.   },
  826.   doCommand: function(aCommand)
  827.   {
  828.     // Launch Object properties for appropriate selected element 
  829.     var element = GetObjectForProperties();
  830.     if (element)
  831.     {
  832.       var name = element.nodeName.toLowerCase();
  833.       switch (name)
  834.       {
  835.         case 'img':
  836.           goDoCommand("cmd_image");
  837.           break;
  838.         case 'hr':
  839.           goDoCommand("cmd_hline");
  840.           break;
  841.         case 'table':
  842.           EditorInsertOrEditTable(false);
  843.           break;
  844.         case 'td':
  845.         case 'th':
  846.           EditorTableCellProperties();
  847.           break;
  848.         case 'ol':
  849.         case 'ul':
  850.         case 'dl':
  851.           goDoCommand("cmd_listProperties");
  852.           break;
  853.         case 'a':
  854.           if (element.name)
  855.           {
  856.             goDoCommand("cmd_anchor");
  857.           }
  858.           else if(element.href)
  859.           {
  860.             goDoCommand("cmd_link");
  861.           }
  862.           break;
  863.         default:
  864.           doAdvancedProperties(element);
  865.           break;
  866.       }
  867.     } else {
  868.       // We get a partially-selected link if asked for specifically
  869.       element = window.editorShell.GetSelectedElement("href");
  870.       if (element)
  871.         goDoCommand("cmd_link");
  872.     }
  873.     window._content.focus();
  874.   }
  875. };
  876.  
  877.  
  878. //-----------------------------------------------------------------------------------
  879. var nsSetSmiley =
  880. {
  881.   isCommandEnabled: function(aCommand, dummy)
  882.   {
  883.     return ( window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  884.  
  885.   },
  886.  
  887.   doCommand: function(aCommand)
  888.   {
  889.     
  890.     var commandNode = document.getElementById(aCommand);
  891.     var smileyCode = commandNode.getAttribute("state");
  892.  
  893.     var strSml;
  894.     switch(smileyCode)
  895.     {
  896.         case ":-)": strSml="s1"; 
  897.         break;
  898.         case ":-(": strSml="s2";
  899.         break;
  900.         case ";-)": strSml="s3";
  901.         break;
  902.         case ":-P": strSml="s4";
  903.         break;
  904.         case ":-D": strSml="s5";
  905.         break;
  906.         case ":-[": strSml="s6";
  907.         break;
  908.         case ":-\\": strSml="s7";
  909.         break;
  910.         default:    strSml="";
  911.         break;
  912.     }
  913.  
  914.     try 
  915.     {
  916.       var selection = window.editorShell.editorSelection;
  917.  
  918.       if (!selection)
  919.         return;
  920.     
  921.       var extElement = editorShell.CreateElementWithDefaults("span");
  922.       if (!extElement)
  923.         return;
  924.     
  925.       extElement.setAttribute("-moz-smiley", strSml);
  926.  
  927.     
  928.       var intElement = editorShell.CreateElementWithDefaults("span");
  929.       if (!intElement)
  930.         return;
  931.  
  932.       //just for mailnews, because of the way it removes HTML
  933.       var smileButMenu = document.getElementById('smileButtonMenu');      
  934.       if (smileButMenu.getAttribute("padwithspace"))
  935.          smileyCode = " " + smileyCode + " ";
  936.  
  937.       var txtElement =  document.createTextNode(smileyCode);
  938.       if (!txtElement)
  939.         return;
  940.  
  941.       intElement.appendChild (txtElement);
  942.       extElement.appendChild (intElement);
  943.  
  944.  
  945.       editorShell.InsertElementAtSelection(extElement,true);
  946.       window._content.focus();        
  947.  
  948.     } 
  949.     catch (e) 
  950.     {
  951.         dump("Exception occured in smiley InsertElementAtSelection\n");
  952.     }
  953.     
  954.   }
  955.  
  956. };
  957.  
  958.  
  959. function doAdvancedProperties(element)
  960. {
  961.   if (element)
  962.   {
  963.     window.openDialog("chrome://editor/content/EdAdvancedEdit.xul", "_blank", "chrome,close,titlebar,modal,resizable=yes", "", element);
  964.     window._content.focus();
  965.   }
  966. }
  967.  
  968. var nsAdvancedPropertiesCommand =
  969. {
  970.   isCommandEnabled: function(aCommand, dummy)
  971.   {
  972.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  973.   },
  974.   doCommand: function(aCommand)
  975.   {
  976.     // Launch AdvancedEdit dialog for the selected element
  977.     var element = window.editorShell.GetSelectedElement("");
  978.     doAdvancedProperties(element);
  979.   }
  980. };
  981.  
  982. //-----------------------------------------------------------------------------------
  983. var nsColorPropertiesCommand =
  984. {
  985.   isCommandEnabled: function(aCommand, dummy)
  986.   {
  987.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  988.   },
  989.   doCommand: function(aCommand)
  990.   {
  991.     window.openDialog("chrome://editor/content/EdColorProps.xul","_blank", "chrome,close,titlebar,modal", ""); 
  992.     window._content.focus();
  993.   }
  994. };
  995.  
  996. //-----------------------------------------------------------------------------------
  997. var nsRemoveLinksCommand =
  998. {
  999.   isCommandEnabled: function(aCommand, dummy)
  1000.   {
  1001.     // We could see if there's any link in selection, but it doesn't seem worth the work!
  1002.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  1003.   },
  1004.   doCommand: function(aCommand)
  1005.   {
  1006.     window.editorShell.RemoveTextProperty("href", "");
  1007.     window._content.focus();
  1008.   }
  1009. };
  1010.  
  1011.  
  1012. //-----------------------------------------------------------------------------------
  1013. var nsNormalModeCommand =
  1014. {
  1015.   isCommandEnabled: function(aCommand, dummy)
  1016.   {
  1017.     return IsEditorContentHTML(); //(window.editorShell && window.editorShell.documentEditable);
  1018.   },
  1019.   doCommand: function(aCommand)
  1020.   {
  1021.     if (gEditorDisplayMode != DisplayModeNormal)
  1022.       SetEditMode(DisplayModeNormal);
  1023.   }
  1024. };
  1025.  
  1026. var nsAllTagsModeCommand =
  1027. {
  1028.   isCommandEnabled: function(aCommand, dummy)
  1029.   {
  1030.     return (window.editorShell && window.editorShell.documentEditable && IsEditorContentHTML());
  1031.   },
  1032.   doCommand: function(aCommand)
  1033.   {
  1034.     if (gEditorDisplayMode != DisplayModeAllTags)
  1035.       SetEditMode(DisplayModeAllTags);
  1036.   }
  1037. };
  1038.  
  1039. var nsHTMLSourceModeCommand =
  1040. {
  1041.   isCommandEnabled: function(aCommand, dummy)
  1042.   {
  1043.     return (window.editorShell && window.editorShell.documentEditable && IsEditorContentHTML());
  1044.   },
  1045.   doCommand: function(aCommand)
  1046.   {
  1047.     if (gEditorDisplayMode != DisplayModeSource)
  1048.       SetEditMode(DisplayModeSource);
  1049.   }
  1050. };
  1051.  
  1052. var nsPreviewModeCommand =
  1053. {
  1054.   isCommandEnabled: function(aCommand, dummy)
  1055.   {
  1056.     return (window.editorShell && window.editorShell.documentEditable && IsEditorContentHTML());
  1057.   },
  1058.   doCommand: function(aCommand)
  1059.   {
  1060.     FinishHTMLSource();
  1061.     if (gEditorDisplayMode != DisplayModePreview)
  1062.       SetEditMode(DisplayModePreview);
  1063.   }
  1064. };
  1065.  
  1066. //-----------------------------------------------------------------------------------
  1067. var nsInsertOrEditTableCommand =
  1068. {
  1069.   isCommandEnabled: function(aCommand, dummy)
  1070.   {
  1071.     return (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML());
  1072.   },
  1073.   doCommand: function(aCommand)
  1074.   {
  1075.     if (IsInTableCell())
  1076.       EditorTableCellProperties();
  1077.     else
  1078.       EditorInsertOrEditTable(true);
  1079.   }
  1080. };
  1081.  
  1082. //-----------------------------------------------------------------------------------
  1083. var nsEditTableCommand =
  1084. {
  1085.   isCommandEnabled: function(aCommand, dummy)
  1086.   {
  1087.     return IsInTable();
  1088.   },
  1089.   doCommand: function(aCommand)
  1090.   {
  1091.     EditorInsertOrEditTable(false);
  1092.   }
  1093. };
  1094.  
  1095. //-----------------------------------------------------------------------------------
  1096. var nsSelectTableCommand =
  1097. {
  1098.   isCommandEnabled: function(aCommand, dummy)
  1099.   {
  1100.     return IsInTable();
  1101.   },
  1102.   doCommand: function(aCommand)
  1103.   {
  1104.     window.editorShell.SelectTable();
  1105.     window._content.focus();
  1106.   }
  1107. };
  1108.  
  1109. var nsSelectTableRowCommand =
  1110. {
  1111.   isCommandEnabled: function(aCommand, dummy)
  1112.   {
  1113.     return IsInTableCell();
  1114.   },
  1115.   doCommand: function(aCommand)
  1116.   {
  1117.     window.editorShell.SelectTableRow();
  1118.     window._content.focus();
  1119.   }
  1120. };
  1121.  
  1122. var nsSelectTableColumnCommand =
  1123. {
  1124.   isCommandEnabled: function(aCommand, dummy)
  1125.   {
  1126.     return IsInTableCell();
  1127.   },
  1128.   doCommand: function(aCommand)
  1129.   {
  1130.     window.editorShell.SelectTableColumn();
  1131.     window._content.focus();
  1132.   }
  1133. };
  1134.  
  1135. var nsSelectTableCellCommand =
  1136. {
  1137.   isCommandEnabled: function(aCommand, dummy)
  1138.   {
  1139.     return IsInTableCell();
  1140.   },
  1141.   doCommand: function(aCommand)
  1142.   {
  1143.     window.editorShell.SelectTableCell();
  1144.     window._content.focus();
  1145.   }
  1146. };
  1147.  
  1148. var nsSelectAllTableCellsCommand =
  1149. {
  1150.   isCommandEnabled: function(aCommand, dummy)
  1151.   {
  1152.     return IsInTable();
  1153.   },
  1154.   doCommand: function(aCommand)
  1155.   {
  1156.     window.editorShell.SelectAllTableCells();
  1157.     window._content.focus();
  1158.   }
  1159. };
  1160.  
  1161. //-----------------------------------------------------------------------------------
  1162. var nsInsertTableCommand =
  1163. {
  1164.   isCommandEnabled: function(aCommand, dummy)
  1165.   {
  1166.     return window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML();
  1167.   },
  1168.   doCommand: function(aCommand)
  1169.   {
  1170.     EditorInsertTable();
  1171.   }
  1172. };
  1173.  
  1174. var nsInsertTableRowAboveCommand =
  1175. {
  1176.   isCommandEnabled: function(aCommand, dummy)
  1177.   {
  1178.     return IsInTableCell();
  1179.   },
  1180.   doCommand: function(aCommand)
  1181.   {
  1182.     window.editorShell.InsertTableRow(1, false);
  1183.     window._content.focus();
  1184.   }
  1185. };
  1186.  
  1187. var nsInsertTableRowBelowCommand =
  1188. {
  1189.   isCommandEnabled: function(aCommand, dummy)
  1190.   {
  1191.     return IsInTableCell();
  1192.   },
  1193.   doCommand: function(aCommand)
  1194.   {
  1195.     window.editorShell.InsertTableRow(1,true);
  1196.     window._content.focus();
  1197.   }
  1198. };
  1199.  
  1200. var nsInsertTableColumnBeforeCommand =
  1201. {
  1202.   isCommandEnabled: function(aCommand, dummy)
  1203.   {
  1204.     return IsInTableCell();
  1205.   },
  1206.   doCommand: function(aCommand)
  1207.   {
  1208.     window.editorShell.InsertTableColumn(1, false);
  1209.     window._content.focus();
  1210.   }
  1211. };
  1212.  
  1213. var nsInsertTableColumnAfterCommand =
  1214. {
  1215.   isCommandEnabled: function(aCommand, dummy)
  1216.   {
  1217.     return IsInTableCell();
  1218.   },
  1219.   doCommand: function(aCommand)
  1220.   {
  1221.     window.editorShell.InsertTableColumn(1, true);
  1222.     window._content.focus();
  1223.   }
  1224. };
  1225.  
  1226. var nsInsertTableCellBeforeCommand =
  1227. {
  1228.   isCommandEnabled: function(aCommand, dummy)
  1229.   {
  1230.     return IsInTableCell();
  1231.   },
  1232.   doCommand: function(aCommand)
  1233.   {
  1234.     window.editorShell.InsertTableCell(1, false);
  1235.   }
  1236. };
  1237.  
  1238. var nsInsertTableCellAfterCommand =
  1239. {
  1240.   isCommandEnabled: function(aCommand, dummy)
  1241.   {
  1242.     return IsInTableCell();
  1243.   },
  1244.   doCommand: function(aCommand)
  1245.   {
  1246.     window.editorShell.InsertTableCell(1, true);
  1247.     window._content.focus();
  1248.   }
  1249. };
  1250.  
  1251. //-----------------------------------------------------------------------------------
  1252. var nsDeleteTableCommand =
  1253. {
  1254.   isCommandEnabled: function(aCommand, dummy)
  1255.   {
  1256.     return IsInTable();
  1257.   },
  1258.   doCommand: function(aCommand)
  1259.   {
  1260.     window.editorShell.DeleteTable();        
  1261.     window._content.focus();
  1262.   }
  1263. };
  1264.  
  1265. var nsDeleteTableRowCommand =
  1266. {
  1267.   isCommandEnabled: function(aCommand, dummy)
  1268.   {
  1269.     return IsInTableCell();
  1270.   },
  1271.   doCommand: function(aCommand)
  1272.   {
  1273.     var rows = GetNumberOfContiguousSelectedRows();
  1274.     // Delete at least one row
  1275.     if (rows == 0)
  1276.       rows = 1;
  1277.  
  1278.     try {
  1279.       window.editorShell.BeginBatchChanges();
  1280.  
  1281.       // Loop to delete all blocks of contiguous, selected rows
  1282.       while (rows)
  1283.       {
  1284.         window.editorShell.DeleteTableRow(rows);
  1285.         rows = GetNumberOfContiguousSelectedRows();
  1286.       }
  1287.       window.editorShell.EndBatchChanges();
  1288.     } catch(ex) {
  1289.       window.editorShell.EndBatchChanges();
  1290.     }
  1291.     window._content.focus();
  1292.   }
  1293. };
  1294.  
  1295. var nsDeleteTableColumnCommand =
  1296. {
  1297.   isCommandEnabled: function(aCommand, dummy)
  1298.   {
  1299.     return IsInTableCell();
  1300.   },
  1301.   doCommand: function(aCommand)
  1302.   {
  1303.     var columns = GetNumberOfContiguousSelectedColumns();
  1304.     // Delete at least one column
  1305.     if (columns == 0)
  1306.       columns = 1;
  1307.  
  1308.     try {
  1309.       window.editorShell.BeginBatchChanges();
  1310.  
  1311.       // Loop to delete all blocks of contiguous, selected columns
  1312.       while (columns)
  1313.       {
  1314.         window.editorShell.DeleteTableColumn(columns);
  1315.         columns = GetNumberOfContiguousSelectedColumns();
  1316.       }
  1317.       window.editorShell.EndBatchChanges();
  1318.     } catch(ex) {
  1319.       window.editorShell.EndBatchChanges();
  1320.     }
  1321.     window._content.focus();
  1322.   }
  1323. };
  1324.  
  1325. var nsDeleteTableCellCommand =
  1326. {
  1327.   isCommandEnabled: function(aCommand, dummy)
  1328.   {
  1329.     return IsInTableCell();
  1330.   },
  1331.   doCommand: function(aCommand)
  1332.   {
  1333.     window.editorShell.DeleteTableCell(1);   
  1334.     window._content.focus();
  1335.   }
  1336. };
  1337.  
  1338. var nsDeleteTableCellContentsCommand =
  1339. {
  1340.   isCommandEnabled: function(aCommand, dummy)
  1341.   {
  1342.     return IsInTableCell();
  1343.   },
  1344.   doCommand: function(aCommand)
  1345.   {
  1346.     window.editorShell.DeleteTableCellContents();
  1347.     window._content.focus();
  1348.   }
  1349. };
  1350.  
  1351.  
  1352. //-----------------------------------------------------------------------------------
  1353. var nsNormalizeTableCommand =
  1354. {
  1355.   isCommandEnabled: function(aCommand, dummy)
  1356.   {
  1357.     return IsInTable();
  1358.   },
  1359.   doCommand: function(aCommand)
  1360.   {
  1361.     // Use nsnull to let editor find table enclosing current selection
  1362.     window.editorShell.NormalizeTable(null);
  1363.     window._content.focus();
  1364.   }
  1365. };
  1366.  
  1367. //-----------------------------------------------------------------------------------
  1368. var nsJoinTableCellsCommand =
  1369. {
  1370.   isCommandEnabled: function(aCommand, dummy)
  1371.   {
  1372.     if (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML())
  1373.     {
  1374.       var tagNameObj = new Object;
  1375.       var countObj = new Object;
  1376.       var cell = window.editorShell.GetSelectedOrParentTableElement(tagNameObj, countObj);
  1377.  
  1378.       // We need a cell and either > 1 selected cell or a cell to the right
  1379.       //  (this cell may originate in a row spanned from above current row)
  1380.       // Note that editorShell returns "td" for "th" also.
  1381.       // (this is a pain! Editor and gecko use lowercase tagNames, JS uses uppercase!)
  1382.       if( cell && (tagNameObj.value == "td"))
  1383.       {
  1384.         // Selected cells
  1385.         if (countObj.value > 1) return true;
  1386.  
  1387.         var colSpan = cell.getAttribute("colspan");
  1388.  
  1389.         // getAttribute returns string, we need number
  1390.         // no attribute means colspan = 1
  1391.         if (!colSpan)
  1392.           colSpan = Number(1);
  1393.         else
  1394.           colSpan = Number(colSpan);
  1395.  
  1396.         // Test if cell exists to the right of current cell
  1397.         // (cells with 0 span should never have cells to the right
  1398.         //  if there is, user can select the 2 cells to join them)
  1399.         return (colSpan != 0 &&
  1400.                 window.editorShell.GetCellAt(null, 
  1401.                                    window.editorShell.GetRowIndex(cell), 
  1402.                                    window.editorShell.GetColumnIndex(cell) + colSpan));
  1403.       }
  1404.     }
  1405.     return false;
  1406.   },
  1407.   doCommand: function(aCommand)
  1408.   {
  1409.     // Param: Don't merge non-contiguous cells
  1410.     window.editorShell.JoinTableCells(false);
  1411.     window._content.focus();
  1412.   }
  1413. };
  1414.  
  1415. //-----------------------------------------------------------------------------------
  1416. var nsSplitTableCellCommand =
  1417. {
  1418.   isCommandEnabled: function(aCommand, dummy)
  1419.   {
  1420.     if (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML())
  1421.     {
  1422.       var tagNameObj = new Object;
  1423.       var countObj = new Object;
  1424.       var cell = window.editorShell.GetSelectedOrParentTableElement(tagNameObj, countObj);
  1425.       // We need a cell parent and there's just 1 selected cell 
  1426.       // or selection is entirely inside 1 cell
  1427.       if ( cell && (tagNameObj.value == "td") && 
  1428.            countObj.value <= 1 &&
  1429.            IsSelectionInOneCell() )
  1430.       {
  1431.         var colSpan = cell.getAttribute("colspan");
  1432.         var rowSpan = cell.getAttribute("colspan");
  1433.         if (!colSpan) colSpan = 1;
  1434.         if (!rowSpan) rowSpan = 1;
  1435.         return (colSpan > 1  || rowSpan > 1 ||
  1436.                 colSpan == 0 || rowSpan == 0);
  1437.       }
  1438.     }
  1439.     return false;
  1440.   },
  1441.   doCommand: function(aCommand)
  1442.   {
  1443.     window.editorShell.SplitTableCell();
  1444.     window._content.focus();
  1445.   }
  1446. };
  1447.  
  1448. //-----------------------------------------------------------------------------------
  1449. var nsTableOrCellColorCommand =
  1450. {
  1451.   isCommandEnabled: function(aCommand, dummy)
  1452.   {
  1453.     return IsInTable();
  1454.   },
  1455.   doCommand: function(aCommand)
  1456.   {
  1457.     EditorSelectColor("TableOrCell");
  1458.   }
  1459. };
  1460.  
  1461.  
  1462. //-----------------------------------------------------------------------------------
  1463. var nsPreferencesCommand =
  1464. {
  1465.   isCommandEnabled: function(aCommand, dummy)
  1466.   {
  1467.     return true;
  1468.   },
  1469.   doCommand: function(aCommand)
  1470.   {
  1471.     goPreferences('navigator.xul', 'chrome://editor/content/pref-composer.xul','editor');
  1472.     window._content.focus();
  1473.   }
  1474. };
  1475.  
  1476.  
  1477. var nsFinishHTMLSource =
  1478. {
  1479.   isCommandEnabled: function(aCommand, dummy)
  1480.   {
  1481.     return true;
  1482.   },
  1483.   doCommand: function(aCommand)
  1484.   {
  1485.     // In editor.js
  1486.     FinishHTMLSource();
  1487.   }
  1488. };
  1489.  
  1490. var nsCancelHTMLSource =
  1491. {
  1492.   isCommandEnabled: function(aCommand, dummy)
  1493.   {
  1494.     return true;
  1495.   },
  1496.   doCommand: function(aCommand)
  1497.   {
  1498.     // In editor.js
  1499.     CancelHTMLSource();
  1500.   }
  1501. };
  1502.  
  1503. var nsBuildRecentPagesMenu =
  1504. {
  1505.   isCommandEnabled: function(aCommand, dummy)
  1506.   {
  1507.     return true;
  1508.   },
  1509.   doCommand: function(aCommand)
  1510.   {
  1511.     // In editor.js. True means save menu to prefs
  1512.     BuildRecentMenu(true);
  1513.   }
  1514. };
  1515.  
  1516. var nsConvertToTable =
  1517. {
  1518.   isCommandEnabled: function(aCommand, dummy)
  1519.   {
  1520.     if (window.editorShell && window.editorShell.documentEditable && IsEditingRenderedHTML())
  1521.     {
  1522.     var selection = window.editorShell.editorSelection;
  1523.  
  1524.     if (selection && !selection.isCollapsed)
  1525.     {
  1526.       // Don't allow if table or cell is the selection
  1527.       var element = window.editorShell.GetSelectedElement("");
  1528.  
  1529.       if (element && (element.nodeName == "td" ||
  1530.                       element.nodeName == "table"))
  1531.         return false;
  1532.  
  1533.       // Selection start and end must be in the same cell
  1534.       //   in same cell or both are NOT in a cell
  1535.       if ( GetParentTableCell(selection.focusNode) !=
  1536.            GetParentTableCell(selection.anchorNode) )
  1537.         return false
  1538.       
  1539.       return true;
  1540.       }
  1541.     }
  1542.     return false;
  1543.   },
  1544.   doCommand: function(aCommand)
  1545.   {
  1546.     if (this.isCommandEnabled())
  1547.     {
  1548.       window.openDialog("chrome://editor/content/EdConvertToTable.xul","_blank", "chrome,close,titlebar,modal")
  1549.     }
  1550.     window._content.focus();
  1551.   }
  1552. };
  1553.  
  1554.